package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.auth.domain.DataNode;
import com.example.auth.domain.User;
import com.example.config.auth.SecurityUtil;
import com.example.config.exception.GlobalExcetion;
import com.example.dto.UserPayRecordInDto;
import com.example.dto.UserPayRecordOutDto;
import com.example.feign.NodeFeignService;
import com.example.feign.UserFeignService;
import com.example.pay.domain.UserMoneyAccount;
import com.example.pay.domain.UserPayRecordIn;
import com.example.pay.domain.UserPayRecordOut;
import com.example.ribbon.service.PayAccountRibbonService;
import com.example.service.UserMoneyAccountService;
import com.example.service.UserPayRecordInService;
import com.example.service.UserPayRecordOutService;
import com.example.system.service.BusSystemTableUserService;
import com.example.util.BigDecimalUtils;
import com.example.util.Results;
import com.example.vo.UserMoneyTransferReceiveVo;
import com.example.vo.UserMoneyTransferVo;
import com.example.vo.UserMoneyVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/usermoney")
public class UserMoneyAccountController {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${spring.application.name}")
    private String appName;

    @Autowired
    private BusSystemTableUserService busSystemTableUserService;

    @Autowired
    private UserMoneyAccountService userMoneyAccountService;

    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    private NodeFeignService nodeFeignService;

    @Autowired
    private UserPayRecordInService userPayRecordInService;

    @Autowired
    private UserPayRecordOutService userPayRecordOutService;

    @Autowired
    private PayAccountRibbonService payAccountRibbonService;




    /**
     * 查询出账记录
     * @param pageNum
     * @param pageSize
     * @return
     * @throws GlobalExcetion
     */
    @GetMapping("/getrecord_out")
    public JSONObject getRecordOut(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                   @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize) throws GlobalExcetion {

        String userId=SecurityUtil.getUserId();
        IPage<UserPayRecordOut> iPage=userPayRecordOutService.page(new Page<>(pageNum,pageSize),userId);
        List<UserPayRecordOutDto> dtoList=new ArrayList<>();
        if(!iPage.getRecords().isEmpty()){
            List<UserPayRecordOut> list=iPage.getRecords();
            for(UserPayRecordOut userPayRecordOut:list){
                UserPayRecordOutDto dto=new UserPayRecordOutDto();
                BeanUtils.copyProperties(userPayRecordOut,dto);
                User toUser=userFeignService.getUserByHashUserId(userPayRecordOut.getToUuid());
                if(toUser!=null){
                    dto.setToUserName("转给："+toUser.getUsername());
                }
                User formUser=userFeignService.getUserByHashUserId(userPayRecordOut.getFromUuid());
                if(formUser!=null){
                    dto.setTitle(formUser.getUsername()+" 的支出");
                    dto.setFormUserName("用户 "+formUser.getUsername());
                }
                dtoList.add(dto);
            }
        }
        JSONObject result=new JSONObject();
        result.put("data",dtoList);
        result.put("total",iPage.getTotal());
        return Results.success(result);
    }

    /**
     * 查询进账
     * @param pageNum
     * @param pageSize
     * @return
     * @throws GlobalExcetion
     */
    @GetMapping("/getrecord_in")
    public JSONObject getRecordIn(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                  @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize) throws GlobalExcetion {
        String userId=SecurityUtil.getUserId();
        IPage<UserPayRecordIn> iPage=userPayRecordInService.page(new Page<>(pageNum,pageSize),userId);
        List<UserPayRecordInDto> dtoList=new ArrayList<>();
        if(!iPage.getRecords().isEmpty()){
            List<UserPayRecordIn> list=iPage.getRecords();
            for(UserPayRecordIn userPayRecordIn:list){
                UserPayRecordInDto dto=new UserPayRecordInDto();
                BeanUtils.copyProperties(userPayRecordIn,dto);
                User toUser=userFeignService.getUserByHashUserId(userPayRecordIn.getToUuid());
                if(toUser!=null){
                    dto.setTitle(toUser.getUsername()+" 的收入");
                    dto.setToUserName("转给: "+toUser.getUsername());
                }
                if(!"system".equals(userPayRecordIn.getFromUuid())){
                    User formUser=userFeignService.getUserByHashUserId(userPayRecordIn.getFromUuid());
                    if(formUser!=null){
                        dto.setFormUserName("用户:"+formUser.getUsername());
                    }
                }
                dtoList.add(dto);
            }
        }
        JSONObject result=new JSONObject();
        result.put("data",dtoList);
        result.put("total",iPage.getTotal());
        return Results.success(result);
    }

    /**
     * 用户转账接收
     */
    @PostMapping("/transfer_accounts_recevie")
    public JSONObject transferRecevie(@Validated @RequestBody UserMoneyTransferReceiveVo vo) throws GlobalExcetion {
        UserMoneyAccount recevieAccount=userMoneyAccountService.getUserMoneyAccountByUserId(vo.getUserId());
        BigDecimal beforeMoney=new BigDecimal(recevieAccount.getUserMoney());
        BigDecimal money=new BigDecimal(vo.getMoney());
        BigDecimal afterMoney=BigDecimalUtils.add(beforeMoney,money);
        recevieAccount.setUserMoney(afterMoney.toString());
        userMoneyAccountService.updateUserMoneyAccountById(recevieAccount);

        DataNode dataNode=nodeFeignService.getDataNodeConfigByServerName(appName);
        //添加进账记录
        UserPayRecordIn userPayRecordIn=new UserPayRecordIn();
        userPayRecordIn.setPayMoney(vo.getMoney());
        userPayRecordIn.setFromUuid(vo.getFromUid());
        userPayRecordIn.setToUuid(vo.getUserId());
        userPayRecordIn.setPayNote(vo.getPayNote());
        userPayRecordIn.setDsNo(dataNode.getId());
        userPayRecordIn.setPayType("入账");
        userPayRecordInService.saveUserPayRecordIn(vo.getUserId(), userPayRecordIn);
        return Results.success("转账成功");
    }

    /**
     * 用户转账
     * @param vo
     * @return
     * @throws GlobalExcetion
     */
    @PostMapping("/transfer_accounts")
    public JSONObject transfer(@Validated @RequestBody UserMoneyTransferVo vo) throws GlobalExcetion {
        String currentId=SecurityUtil.getUserId();
        //当前用户账户
        UserMoneyAccount account=userMoneyAccountService.getUserMoneyAccountByUserId(currentId);
        BigDecimal currentMoney=new BigDecimal(account.getUserMoney());
        BigDecimal transferMoney=new BigDecimal(vo.getMoney());
        if(!BigDecimalUtils.ge(currentMoney,transferMoney)){
            throw new GlobalExcetion(1,"转账余额不足");
        }
        //转账接收目标用户有可能不在当前节点，所以需要使用ribbon
        User toUser=userFeignService.getUserByHashUserName(vo.getUserName());
        if(toUser==null){
            throw new GlobalExcetion(1,"转账用户不存在");
        }
        if(!passwordEncoder.matches(vo.getPayPassword(),account.getPayPassword())){
            throw new BadCredentialsException("支付密码错误");
        }
        BigDecimal afterMoney=BigDecimalUtils.subtract(currentMoney,transferMoney);
        account.setUserMoney(afterMoney.toString());
        userMoneyAccountService.updateUserMoneyAccountById(account);


        payAccountRibbonService.transferRecevie(toUser.getUuid(),currentId, vo.getMoney(), vo.getPayNote());

        DataNode dataNode=nodeFeignService.getDataNodeConfigByServerName(appName);
        //生成出账记录
        UserPayRecordOut payRecordOut=new UserPayRecordOut();
        payRecordOut.setPayMoney(vo.getMoney());
        payRecordOut.setFromUuid(currentId);
        payRecordOut.setToUuid(toUser.getUuid());
        payRecordOut.setPayNote(vo.getPayNote());
        payRecordOut.setPayType("出账");
        payRecordOut.setDsNo(dataNode.getId());
        //保存出账记录
        userPayRecordOutService.saveUserPayRecordOut(currentId,payRecordOut);
        return Results.success("转账成功");
    }

    /**
     * 充值
     * @param vo
     * @return
     * @throws GlobalExcetion
     */
    @PostMapping("/insvert_money")
    public JSONObject insertMoney(@RequestBody UserMoneyVo vo) throws GlobalExcetion {
        userMoneyAccountService.insertMoney(vo);
        return Results.success("充值成功");
    }

    /**
     * 查询余额信息
     * @return
     * @throws GlobalExcetion
     */
    @GetMapping("info")
    public JSONObject myInfo() throws GlobalExcetion {
        String userId= SecurityUtil.getUserId();
        User user=userFeignService.getUserByHashUserId(userId);
        UserMoneyAccount account=userMoneyAccountService.info(user);
        account.setPayPassword(null);
        return Results.success(account);
    }

}
